package org.ala.tiktools.pacemaker.queues;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * 起搏器专用的queue
 * <p>  迭代时，会切换成新的queue
 * <p>  空间换时间
 * @author ala
 * @date 2024-12-18 16:10
 */
public class PacemakerQueue<T> {

    /**
     *  当前任务队列
     */
    protected LinkedBlockingQueue<T> queue;
    /**
     *  计数
     */
    protected AtomicInteger count = new AtomicInteger(0);
    /**
     * 是否正在切换
     */
    protected volatile boolean iterate = false;

    public PacemakerQueue() {
        queue = new LinkedBlockingQueue<T>();
    }


    /**
     *
     */
    public int size() {
        return count.get();
    }
    public boolean isEmpty() {
        return queue.isEmpty();
    }
    /**
     *  吃任务
     */
    public int offer(T t) {
        //  如果正在切换，阻塞
        while (iterate) {}
        queue.offer(t);
        return count.incrementAndGet();
    }
    /**
     *  清空遍历
     *  <p> 开始遍历的那一刻，遍历queue和原queue便不再是同一个queue
     */
    public void clearForEach(Consumer<T> consumer) {
        //  切换
        iterate = true;
        LinkedBlockingQueue<T> queue = this.queue;
        try {
            this.queue = new LinkedBlockingQueue<T>();
            this.count.set(0);
        } finally {
            iterate = false;
        }
        queue.forEach(consumer);
        //  整体释放掉，帮助gc回收
        queue.clear();
    }
}
